package cc.rengu.igas.channel.upac.core.service.trans;

import cc.rengu.igas.channel.upac.common.constant.UpacConfigConstant;
import cc.rengu.igas.channel.upac.common.constant.UpacParamConstant;
import cc.rengu.igas.channel.upac.common.constant.UpacTreeNodeConstant;
import cc.rengu.igas.channel.upac.common.enums.RespCodeEnum;
import cc.rengu.igas.channel.upac.common.enums.SignTypeEnum;
import cc.rengu.igas.channel.upac.common.enums.UpacChannelTypeEunm;
import cc.rengu.igas.channel.upac.common.enums.UpacProdEnum;
import cc.rengu.igas.channel.upac.common.util.UpacSecurityUtil;
import cc.rengu.igas.channel.upac.facade.bean.TokenPayInfo;
import cc.rengu.igas.channel.upac.facade.request.TokenPayOpenByOrderIdRequest;
import cc.rengu.igas.channel.upac.facade.request.UpacWapPayResultNoticeRequest;
import cc.rengu.igas.channel.upac.facade.response.TokenPayOpenByOrderIdResponse;
import cc.rengu.oltp.service.base.BizBaseService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.dao.CertInfoMapper;
import cc.rengu.oltp.service.common.dao.SignAcctInfoMapper;
import cc.rengu.oltp.service.common.dao.SysParamMapper;
import cc.rengu.oltp.service.common.dao.impl.CertInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.SignAcctInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.SysParamMapperImpl;
import cc.rengu.oltp.service.common.entity.*;
import cc.rengu.oltp.service.model.RiskMonitorInfo;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.utility.annotation.BIZ_PROCESS;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import org.apache.commons.codec.binary.Base64;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 银联全渠道手机WAP支付结果通知服务
 * Created by 王成 on 2018/6/4.
 */
public class UpacWapPayResultNoticeService extends BizBaseService {
    @Override
    protected Object beforeBizProcess() throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        CertInfo encryptCertInfo = null;

        NonFinanceTxn nonFinanceTxn = new NonFinanceTxn();
        UpacWapPayResultNoticeRequest upacWapPayResultNoticeRequest = new UpacWapPayResultNoticeRequest();
        ConvertUtil.convertOutput(upacWapPayResultNoticeRequest);
        //解密卡号
        String encoding = XmlConfigUtil.getXmlConfigCacheKeyValue(UpacConfigConstant.UPAC_CONF_NODE, UpacConfigConstant.UPAC_ENCODING);
        encoding = (null == encoding) ? UpacParamConstant.UTF_8_ENCODING : encoding;
        String acctNoEncType = XmlConfigUtil.getXmlConfigCacheKeyValue(UpacConfigConstant.UPAC_CONF_NODE, UpacConfigConstant.UPAC_ACCT_ENC);
        if ("1".equals(acctNoEncType) && upacWapPayResultNoticeRequest.getPayAcctNo() != null) {
            /* 获取敏感信息解密证书 */
            String secPlanInfoListString = xmlTreeUtil.getXmlTreeStringValue(UpacTreeNodeConstant.SEC_PLAN_INFO_LIST);
            List<SecPlanInfo> secPlanInfoList = JSONArray.parseArray(secPlanInfoListString, SecPlanInfo.class);
            Optional<SecPlanInfo> encryptSecPlanOpt = secPlanInfoList.stream().filter(item -> item.getSecPlanType().equals(UpacParamConstant.DECRYPT_CERT_TYPE)).findFirst();
            if (encryptSecPlanOpt.isPresent()) {
                CertInfoMapper certInfoMapper = new CertInfoMapperImpl();
                encryptCertInfo = certInfoMapper.selectCertInfoByPrimaryKey(encryptSecPlanOpt.get().getSecPlanId() + encryptSecPlanOpt.get().getSecPlanType());
            }

            String acctNo = UpacSecurityUtil.decryptData(upacWapPayResultNoticeRequest.getPayAcctNo(), encryptCertInfo.getCertValue(), encoding);
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.PAYER_ACCT_INFO, acctNo);
            upacWapPayResultNoticeRequest.setPayAcctNo(acctNo);
        }
        ConvertUtil.convertOutput(nonFinanceTxn);
        nonFinanceTxn.setPayAcctType(upacWapPayResultNoticeRequest.getPayAcctType());
        nonFinanceTxn.setMchntOrderId(upacWapPayResultNoticeRequest.getMchntOrderId());
        //nonFinanceTxn.setFrontSeqNum(upacWapPayResultNoticeRequest.getTraceNo());
        ConvertUtil.convertInput(nonFinanceTxn);
        return upacWapPayResultNoticeRequest;
    }

    @Override
    protected BizResponse callBizService(Object request) throws Exception {
        int iReturnCode = 0;
        String flag = null;
        String userId = null;
        String chnlId = null;
        CertInfo encryptCertInfo = null;
        String phoneNo = " ";
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        UpacWapPayResultNoticeRequest upacWapPayResultNoticeRequest = (UpacWapPayResultNoticeRequest) request;
        String orderId = upacWapPayResultNoticeRequest.getMchntOrderId();
        Map<String, String> remarkMap = new HashMap<>();
        if (null != upacWapPayResultNoticeRequest.getRemark()) {
            String reqReserved = new String(Base64.decodeBase64(upacWapPayResultNoticeRequest.getRemark()));
            rglog.info("reqReserved=[{}]", reqReserved);
            remarkMap = UpacSecurityUtil.parseJsonString(reqReserved);
            if (remarkMap.get("IgasOrderId") != null) {
                orderId = remarkMap.get("IgasOrderId");
            }
            flag = remarkMap.get("Flag");
            userId = remarkMap.get("UserId");
            if (userId != null) {
                phoneNo = userId;
            }
            chnlId = remarkMap.get("ChanlId");
        }
        xmlTreeUtil.copyStringValue(TreeNodeConstant.SYS_SEQ_NUM, TreeNodeConstant.FRONT_SEQ_NUM);
        /* 根据订单号查询原订单信息,订单号优先从保留域获取 */
        /*OrderInfoMapper orderInfoMapper = new OrderInfoMapperImpl();
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        OrderInfo payOrderInfo = orderInfoMapper.selectIgasOrderInfoByOrderId(instId,orderId);
        if (null == payOrderInfo){
            rglog.error("获取支付订单信息失败,payOrderId:<{}>,",orderId);
            throw new BizException(RespCodeEnum.GET_PAY_ORDER_INFO_ERROR.getRespCode(),RespCodeEnum.GET_PAY_ORDER_INFO_ERROR.getRespDesc());
        }
        *//* 判断订单处理结果 *//*
        if (OrderStatusEnum.PAY_CANCLE.getStatus().equals(payOrderInfo.getOrderStatus()) ||
                OrderStatusEnum.PAY_REFUND.getStatus().equals(payOrderInfo.getOrderStatus()) ||
                OrderStatusEnum.CLOSED.getStatus().equals(payOrderInfo.getOrderStatus())){
            rglog.error("当前订单状态<{}>不允许操作!",payOrderInfo.getOrderStatus());
            throw new BizException(RespCodeEnum.GET_PAY_ORDER_INFO_ERROR.getRespCode(),RespCodeEnum.GET_PAY_ORDER_INFO_ERROR.getRespDesc());
        }*/

        /* 判断金额是否一致 ,组合支付金额可能不一致*/
        /*String orderAmt = String.valueOf(payOrderInfo.getOrderAmt());
        if(AmountUtil.compare(orderAmt, upacWapPayResultNoticeRequest.getTransAmt()) != 0){
            rglog.error("订单金额不一致,原订单金额orderAmt:<{}>,通知金额txnAmt=<{}>",orderAmt,upacWapPayResultNoticeRequest.getTransAmt());
            throw new BizException(RespCodeEnum.GET_PAY_ORDER_INFO_ERROR.getRespCode(),RespCodeEnum.GET_PAY_ORDER_INFO_ERROR.getRespDesc());
        }*/
       /* iReturnCode = orderInfoMapper.updateIgasOrderStatusAndPayId(instId,payOrderInfo.getOrderId(),OrderStatusEnum.PAY_SUCCESS.getStatus(), PayStatusEnum.SUCCESS.getStatus(),payOrderInfo.getPayId());
        if (0 != iReturnCode) {
            rglog.error("更新支付订单状态失败,orderId:<{}>,OrderStatus:<{}>,payStatus:<{}>", payOrderInfo.getOrderId(), OrderStatusEnum.PAY_SUCCESS.getStatus(), PayStatusEnum.SUCCESS.getStatus());
            throw new BizException(RespCodeEnum.UPDATE_ORDER_STATUS_ERROR.getRespCode(), RespCodeEnum.UPDATE_ORDER_STATUS_ERROR.getRespDesc());
        }*/

        if (null != flag && UpacProdEnum.TOKEN_PAY.getProdCode().equals(upacWapPayResultNoticeRequest.getBizProd())) {

            //判断是否是首次开通并支付交易，首次开通并支付获取调用接口获取token信息
            if ("1".equals(flag)) {
                TokenPayOpenByOrderIdRequest tokenPayOpenByOrderIdRequest = new TokenPayOpenByOrderIdRequest();
                ConvertUtil.convertOutput(tokenPayOpenByOrderIdRequest);
                if ("MAIL".equals(chnlId)) {
                    tokenPayOpenByOrderIdRequest.setChannelType(UpacChannelTypeEunm.INTERNET.getChannelType());
                } else {
                    tokenPayOpenByOrderIdRequest.setChannelType(UpacChannelTypeEunm.MOBILE.getChannelType());
                }
                String trId = XmlConfigUtil.getXmlConfigCacheKeyValue(UpacConfigConstant.UPAC_CONF_NODE, "defaultTrId");
                String tokenType = XmlConfigUtil.getXmlConfigCacheKeyValue(UpacConfigConstant.UPAC_CONF_NODE, "defaultTokenType");
                TokenPayInfo tokenPayInfoObj = new TokenPayInfo();
                tokenPayInfoObj.setTrId(trId);
                tokenPayInfoObj.setTokenType(tokenType);
                //tokenPayOpenByOrderIdRequest.setTokenPayInfo(tokenPayInfoObj);
               /* UpacService upacService = new UpacServiceImpl();
                TokenPayOpenByOrderIdResponse tokenPayOpenByOrderIdResponse = upacService.upacPayOpenByOrderId(tokenPayOpenByOrderIdRequest);
                if(!"00".equals(tokenPayOpenByOrderIdResponse.getRespCode())){
                    rglog.error("调用银联全渠道服务失败,respCode=[{}],respDesc{}",tokenPayOpenByOrderIdResponse.getRespCode(),tokenPayOpenByOrderIdResponse.getRespDesc());
                    throw new BizException(tokenPayOpenByOrderIdResponse.getRespCode(),tokenPayOpenByOrderIdResponse.getRespDesc());
                }*/
                TokenPayOpenByOrderIdResponse tokenPayOpenByOrderIdResponse = new TokenPayOpenByOrderIdResponse();
                tokenPayOpenByOrderIdResponse.setIssInsCode("ABC");//测试写死
                /* 获取发卡机构信息 */
                SysParamMapper sysParamMapper = new SysParamMapperImpl();
                SysParam sysParam = sysParamMapper.selectSysParamByPrimaryKey("instId", "ISS_INST_CODE", tokenPayOpenByOrderIdResponse.getIssInsCode());
                if (null == sysParam) {
                    rglog.error("无此发卡行<{}>配置信息，请更参数表!", tokenPayOpenByOrderIdResponse.getIssInsCode());
                    throw new BizException(RespCodeEnum.GET_CARD_BIN_INFO_ERROR.getRespCode(), RespCodeEnum.GET_CARD_BIN_INFO_ERROR.getRespDesc());
                }

                /* 登记签约信息表 */
                SignAcctInfo signAcctInfo = new SignAcctInfo();
                signAcctInfo.setInstId(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID));
                signAcctInfo.setSignType(SignTypeEnum.UPAC_PAY.getSignType());
                signAcctInfo.setSignBankNo(sysParam.getParamValue());
                signAcctInfo.setSignBankName(sysParam.getParamDesc().trim());
                signAcctInfo.setSignAcctNo(tokenPayOpenByOrderIdResponse.getPayAcctNo());
                if (tokenPayOpenByOrderIdResponse.getPayCardType() != null) {
                    signAcctInfo.setSignAcctType(tokenPayOpenByOrderIdResponse.getPayCardType());
                } else {
                    signAcctInfo.setSignAcctType(" ");
                }
                signAcctInfo.setDayLimitAmt("0");
                signAcctInfo.setSingleLimitAmt("0");
                signAcctInfo.setSignDate(DateUtil.getCurrentDate());
                signAcctInfo.setSignExpiryDate(UpacParamConstant.DEFAULT_EXPIRY_DATE);
                signAcctInfo.setSignToken(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM));
                signAcctInfo.setSignStatus(tokenPayOpenByOrderIdResponse.getActivateStatus());
                signAcctInfo.setUserId(userId);
                signAcctInfo.setCardHoldName(" ");
                signAcctInfo.setCertType(" ");
                signAcctInfo.setCertNo(" ");
                if (tokenPayOpenByOrderIdResponse.getCustomerInfo() != null) {
                    Map<String, String> customer = new HashMap<>();
                    String customerInfo = new String(Base64.decodeBase64(""));
                    rglog.info("customerInfo=[{}]", customerInfo);
                    customer = UpacSecurityUtil.convertResultString2Map(customerInfo);
                    if (customer.get("customerNm") != null) {
                        signAcctInfo.setCardHoldName(customer.get("customerNm"));
                    }
                    if (customer.get("certifTp") != null) {
                        signAcctInfo.setCertType(customer.get("certifTp"));
                    }
                    if (customer.get("certifId") != null) {
                        signAcctInfo.setCertNo(customer.get("certifId"));
                    }
                    rglog.debug("encryptedInfo=[{}]", customer.get("encryptedInfo"));
                    if (customer.get("encryptedInfo") != null) {
                        /* 获取敏感信息解密证书 */
                        String encoding = XmlConfigUtil.getXmlConfigCacheKeyValue(UpacConfigConstant.UPAC_CONF_NODE, UpacConfigConstant.UPAC_ENCODING);
                        encoding = (null == encoding) ? UpacParamConstant.UTF_8_ENCODING : encoding;
                        String secPlanInfoListString = xmlTreeUtil.getXmlTreeStringValue(UpacTreeNodeConstant.SEC_PLAN_INFO_LIST);
                        List<SecPlanInfo> secPlanInfoList = JSONArray.parseArray(secPlanInfoListString, SecPlanInfo.class);
                        Optional<SecPlanInfo> encryptSecPlanOpt = secPlanInfoList.stream().filter(item -> item.getSecPlanType().equals(UpacParamConstant.DECRYPT_CERT_TYPE)).findFirst();
                        if (encryptSecPlanOpt.isPresent()) {
                            CertInfoMapper certInfoMapper = new CertInfoMapperImpl();
                            encryptCertInfo = certInfoMapper.selectCertInfoByPrimaryKey(encryptSecPlanOpt.get().getSecPlanId() + encryptSecPlanOpt.get().getSecPlanType());
                        }

                        String encryptedInfo = UpacSecurityUtil.decryptData(customer.get("encryptedInfo"), encryptCertInfo.getCertValue(), encoding);
                        rglog.debug("encryptedInfo=[{}]", encryptedInfo);
                        Map<String, String> encryptedInfoMap = new HashMap<>();
                        encryptedInfoMap = UpacSecurityUtil.convertResultString2Map(encryptedInfo);
                        if (encryptedInfoMap.get("phoneNo") != null) {
                            phoneNo = encryptedInfoMap.get("phoneNo");
                        }
                    }
                }
                signAcctInfo.setReserveMobileNo(phoneNo);
                String tokenPayInfo = JSON.toJSONString(UpacSecurityUtil.parseJsonString(""));
                rglog.info("tokenPayInfo=[{}]", tokenPayInfo);
                signAcctInfo.setOtherSignData(tokenPayInfo);
                signAcctInfo.setSignTokenInst(signAcctInfo.getSignInst());
                SignAcctInfoMapper signInfoMapper = new SignAcctInfoMapperImpl();
                iReturnCode = signInfoMapper.insertSignAcctInfo(signAcctInfo);
                if (0 != iReturnCode) {
                    rglog.error("登记签约信息表失败，iReturnCode:<{}>", iReturnCode);
                    throw new BizException(RespCodeEnum.INSERT_SIGN_INFO_ERROR.getRespCode(), RespCodeEnum.INSERT_SIGN_INFO_ERROR.getRespDesc());
                }

            }
        }

        /* 查找BIZ_PROCESS的注解，基于注解实现不同场景的业务逻辑 */
        invokeBizAnnoMethod(BIZ_PROCESS.class);

        BizResponse bizResponse = new BizResponse();
        bizResponse.setRspSysId(AppParamConstant.IGAS);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        return bizResponse;
    }

    @Override
    protected void afterBizProcess(BizResponse response) throws Exception {

    }

    @Override
    protected RiskMonitorInfo getRiskMonitorInfo() {
        return null;
    }
}
